using System.Collections.Generic;
using Infinity.Common;
using Infinity.Common.Patterns;
using Infinity.Statements.Declare;
using Infinity.Statements.Program;

namespace Infinity.Statements.StatementFactory
{
	public class Scope : Singleton<Scope>, IScope
	{
		/// <summary>
		/// Default constructor
		/// </summary>
		public Scope()
		{
			Variables = new Dictionary<string, IVariableStatement>();
			Functions = new Dictionary<string, IProgramStatement>();
			CurrentNamespace = string.Empty;
			NamespaceCollection = new List<string>();
		}

		public void RegisterVariable(IVariableStatement variable)
		{
			Ensure.NotNull(variable);
			Ensure.NotBlank(variable.Name);

			IVariableStatement result;
			if (!Variables.TryGetValue(variable.Name, out result))
				Variables.Add(variable.Name, variable);
			else
				Error.ThrowException(string.Format("The scopes already contains '{0}' name variable!", variable.Name));
		}

		public void RegisterFunction(IProgramStatement function)
		{
			Ensure.NotNull(function);
			Ensure.NotBlank(function.Name);

			IProgramStatement result;
			if (!Functions.TryGetValue(function.Name, out result))
				Functions.Add(function.Name, function);
			else
				Error.ThrowException(string.Format("The scope already contains '{0}' of '{1}' function!", function.Name,
				                                   function.GetType().FullName));
		}

		public IDictionary<string, IVariableStatement> Variables { get; protected set; }
		public IDictionary<string, IProgramStatement> Functions { get; protected set; }
		public string CurrentNamespace { get; set; }
		public IStatementBase ScopeStatement { get; set; }
		public List<string> NamespaceCollection { get; protected set; }
	}
}